package uk.co.q3c.deplan.client.ui.command;

import java.util.logging.Logger;

import uk.co.q3c.deplan.client.Orchestrator;
import uk.co.q3c.deplan.client.domain.DomainKind;
import uk.co.q3c.deplan.client.domain.dag.ChangeInvalidException;
import uk.co.q3c.deplan.client.domain.dag.CycleDetectedException;
import uk.co.q3c.deplan.client.domain.resource.PersistenceReferenceException;
import uk.co.q3c.deplan.client.domain.task.BaseTask;
import uk.co.q3c.deplan.client.domain.task.Task;

import com.google.gwt.user.client.Command;

/**
 * Creates a new sub task and makes it a child of the supplied parent task. If no parent task is specified, an error is logged and the call
 * ignored. TaskType must also be set before execution.
 * 
 * @author dsowerby
 * 
 */
public class AddNewSubTaskCommand implements Command {
	protected static final Logger logger = Logger.getLogger(AddNewSubTaskCommand.class.getName());
	private BaseTask parentTask;
	private DomainKind taskType;

	@Override
	public void execute() {
		if (parentTask == null) {
			String msg = "Parent task must be set in order to add subtask";
			logger.severe(msg);
			throw new RuntimeException(msg);
		}
		if (taskType == null) {
			String msg = "Task type must be set in order to add subtask";
			logger.severe(msg);
			throw new RuntimeException(msg);
		}
		Task subTask = createTask();
		try {
			subTask.setParentTask(parentTask);
		} catch (CycleDetectedException e) {
			logger.severe("Cannot set this parent");
		} catch (ChangeInvalidException e) {
			logger.severe("Cannot set this parent");
		} catch (PersistenceReferenceException e) {
			logger.severe("Cannot set this parent");
		}
	}

	private Task createTask() {
		switch (taskType) {
		case AbstractTask:
			return new BaseTask(Orchestrator.serviceFactory());

		default:
			String msg = "Sub task creation is not specified for domain kind " + taskType;
			logger.severe(msg);
			throw new RuntimeException(msg);

		}
	}

	public void setParentTask(BaseTask parentTask) {
		this.parentTask = parentTask;
	}

	public BaseTask getParentTask() {
		return parentTask;
	}

	public void setTaskType(DomainKind taskType) {
		this.taskType = taskType;
	}

	public DomainKind getTaskType() {
		return taskType;
	}

}
